use crate::client::http::build_client;
use crate::types::{EmOptionTick, OptionValueAnalysis, OptionRiskAnalysis, OptionPremiumAnalysis, OptionMinute, Result};
use serde_json::Value;

/// 东方财富-期权市场快照
/// 
/// 获取全市场期权实时行情数据，包括商品期权和金融期权
/// 数据来源：东方财富 push2 API + 中金所期货 API
/// 
/// # 返回
/// - `Vec<EmOptionTick>`: 期权行情列表，包含代码、名称、最新价、涨跌幅、成交量、持仓量等
/// 
/// # 示例
/// ```no_run
/// use akoption::option_current_em;
/// 
/// #[tokio::main]
/// async fn main() -> anyhow::Result<()> {
///     let data = option_current_em().await?;
///     println!("获取到 {} 条期权数据", data.len());
///     Ok(())
/// }
/// ```
pub async fn option_current_em() -> Result<Vec<EmOptionTick>> {
    // 从两个数据源获取数据
    // push2 API可能失效，失败时只使用中金所API
    let mut em_data = match fetch_em_options().await {
        Ok(data) => data,
        Err(e) => {
            eprintln!("警告: push2 API调用失败 ({}), 仅使用中金所数据", e);
            Vec::new()
        }
    };
    
    let cffex_data = fetch_cffex_options().await?;
    
    // 合并数据
    em_data.extend(cffex_data);
    Ok(em_data)
}

/// Fetch options from Eastmoney push2 API (paginated)
async fn fetch_em_options() -> Result<Vec<EmOptionTick>> {
    // 尝试新的API地址
    let url = "https://push2.eastmoney.com/api/qt/clist/get";
    let client = build_client()?;
    
    let mut all_data = Vec::new();
    let mut page = 1;
    let page_size = 500;
    
    loop {
        let params = [
            ("pn", page.to_string()),
            ("pz", page_size.to_string()),
            ("po", "1".to_string()),
            ("np", "1".to_string()),
            ("ut", "bd1d9ddb04089700cf9c27f6f7426281".to_string()),
            ("fltt", "2".to_string()),
            ("invt", "2".to_string()),
            ("fid", "f3".to_string()),
            ("fs", "m:10,m:12,m:140,m:141,m:151,m:163,m:226".to_string()),
            ("fields", "f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f12,f13,f14,f15,f16,f17,f18,f20,f21,f23,f24,f25,f22,f28,f11,f62,f128,f136,f115,f152,f133,f108,f163,f161,f162".to_string()),
        ];
        
        // 添加Referer头以避免反爬虫
        let resp = client.get(url)
            .header("Referer", "https://data.eastmoney.com/")
            .query(&params)
            .send()
            .await?;
        
        let json: Value = resp.json().await?;
        
        // 检查是否有data字段
        let data_obj = match json.get("data") {
            Some(data) if !data.is_null() => data.as_object(),
            _ => {
                // 如果第一页就没有数据,可能是API失效,直接返回空
                if page == 1 {
                    eprintln!("警告: push2 API 可能已失效,返回空数据");
                    return Ok(Vec::new());
                }
                break;
            }
        };
        
        let data_obj = data_obj.ok_or_else(|| anyhow::anyhow!("No data object in EM response"))?;
        
        let diff = match data_obj.get("diff").and_then(|v| v.as_array()) {
            Some(arr) => arr,
            None => break,
        };
        
        if diff.is_empty() {
            break;
        }
        
        // Parse each row
        for item in diff {
            if let Some(obj) = item.as_object() {
                all_data.push(EmOptionTick {
                    code: obj.get("f12").and_then(|v| v.as_str()).unwrap_or("").to_string(),
                    name: obj.get("f14").and_then(|v| v.as_str()).unwrap_or("").to_string(),
                    last: obj.get("f2").and_then(|v| v.as_f64()),
                    change: obj.get("f4").and_then(|v| v.as_f64()),
                    change_pct: obj.get("f3").and_then(|v| v.as_f64()),
                    volume: obj.get("f5").and_then(|v| v.as_f64()),
                    amount: obj.get("f6").and_then(|v| v.as_f64()),
                    open_interest: obj.get("f133").and_then(|v| v.as_f64()),
                    strike: obj.get("f152").and_then(|v| v.as_f64()),
                    days_remaining: obj.get("f161").and_then(|v| v.as_i64()),
                });
            }
        }
        
        // Check if we have more pages
        let total = data_obj.get("total").and_then(|v| v.as_i64()).unwrap_or(0);
        if all_data.len() >= total as usize {
            break;
        }
        
        page += 1;
    }
    
    Ok(all_data)
}

/// Fetch CFFEX options from Eastmoney futures API
async fn fetch_cffex_options() -> Result<Vec<EmOptionTick>> {
    let url = "https://futsseapi.eastmoney.com/list/option/221";
    let client = build_client()?;
    
    let params = [
        ("orderBy", "zdf"),
        ("sort", "desc"),
        ("pageSize", "20000"),
        ("pageIndex", "0"),
        ("token", "58b2fa8f54638b60b87d69b31969089c"),
        ("field", "dm,sc,name,p,zsjd,zde,zdf,f152,vol,cje,ccl,xqj,syr,rz,zjsj,o"),
        ("blockName", "callback"),
    ];
    
    let resp = client.get(url).query(&params).send().await?;
    let json: Value = resp.json().await?;
    
    let list = json["list"].as_array()
        .ok_or_else(|| anyhow::anyhow!("No list in CFFEX response"))?;
    
    let mut result = Vec::new();
    for item in list {
        if let Some(obj) = item.as_object() {
            result.push(EmOptionTick {
                code: obj.get("dm").and_then(|v| v.as_str()).unwrap_or("").to_string(),
                name: obj.get("name").and_then(|v| v.as_str()).unwrap_or("").to_string(),
                last: obj.get("p").and_then(|v| v.as_f64()),
                change: obj.get("zde").and_then(|v| v.as_f64()),
                change_pct: obj.get("zdf").and_then(|v| v.as_f64()),
                volume: obj.get("vol").and_then(|v| v.as_f64()),
                amount: obj.get("cje").and_then(|v| v.as_f64()),
                open_interest: obj.get("ccl").and_then(|v| v.as_f64()),
                strike: obj.get("xqj").and_then(|v| v.as_f64()),
                days_remaining: obj.get("syr").and_then(|v| v.as_i64()),
            });
        }
    }
    
    Ok(result)
}

/// 东方财富-期权价值分析
/// 
/// 获取期权的内在价值、时间价值、隐含波动率等价值分析指标
/// 目标地址: https://data.eastmoney.com/other/valueAnal.html
/// 
/// # 返回
/// - `Vec<OptionValueAnalysis>`: 包含期权代码、名称、最新价、时间价值、内在价值、
///   隐含波动率、标的最新价、标的近一年波动率、到期日等字段
/// 
/// # 示例
/// ```no_run
/// use akoption::option_value_analysis_em;
/// 
/// #[tokio::main]
/// async fn main() -> anyhow::Result<()> {
///     let data = option_value_analysis_em().await?;
///     for item in data.iter().take(5) {
///         println!("{}: 内在价值={:?}, 时间价值={:?}", 
///                  item.name, item.intrinsic_value, item.time_value);
///     }
///     Ok(())
/// }
/// ```
pub async fn option_value_analysis_em() -> Result<Vec<OptionValueAnalysis>> {
    let url = "https://push2.eastmoney.com/api/qt/clist/get";
    let client = build_client()?;
    
    let mut all_data = Vec::new();
    let mut page = 1;
    
    loop {
        let params = [
            ("fid", "f301"),
            ("po", "1"),
            ("pz", "500"),
            ("pn", &page.to_string()),
            ("np", "1"),
            ("fltt", "2"),
            ("invt", "2"),
            ("ut", "b2884a393a59ad64002292a3e90d46a5"),
            ("fields", "f2,f12,f14,f298,f299,f330,f331,f301,f152"),
            ("fs", "m:10"),
        ];
        
        let resp = client.get(url).query(&params).send().await?;
        let json: Value = resp.json().await?;
        
        let data_list = json["data"]["diff"]
            .as_array()
            .ok_or_else(|| anyhow::anyhow!("No data in value analysis response"))?;
        
        if data_list.is_empty() {
            break;
        }
        
        for item in data_list {
            if let Some(obj) = item.as_object() {
                all_data.push(OptionValueAnalysis {
                    code: obj.get("f12").and_then(|v| v.as_str()).unwrap_or("").to_string(),
                    name: obj.get("f14").and_then(|v| v.as_str()).unwrap_or("").to_string(),
                    last: obj.get("f2").and_then(|v| v.as_f64()),
                    change_pct: None, // 不在此接口中
                    intrinsic_value: obj.get("f330").and_then(|v| v.as_f64()),
                    time_value: obj.get("f299").and_then(|v| v.as_f64()),
                    leverage: None, // 不在此接口中
                    actual_leverage: None, // 不在此接口中
                    underlying_last: obj.get("f301").and_then(|v| v.as_f64()),
                    underlying_volatility: obj.get("f298").and_then(|v| v.as_f64()),
                    expire_date: obj.get("f152").and_then(|v| v.as_str()).unwrap_or("").to_string(),
                });
            }
        }
        
        if data_list.len() < 500 {
            break;
        }
        page += 1;
    }
    
    Ok(all_data)
}

/// 东方财富-期权风险分析
/// 
/// 获取期权的 Greeks 指标（Delta、Gamma、Vega、Theta、Rho）和隐含波动率
/// 目标地址: https://data.eastmoney.com/other/riskanal.html
/// 
/// # 返回
/// - `Vec<OptionRiskAnalysis>`: 包含期权代码、名称、最新价、涨跌幅、Delta、Gamma、
///   Vega、Theta、Rho、隐含波动率、到期日等字段
/// 
/// # 示例
/// ```no_run
/// use akoption::option_risk_analysis_em;
/// 
/// #[tokio::main]
/// async fn main() -> anyhow::Result<()> {
///     let data = option_risk_analysis_em().await?;
///     for item in data.iter().take(5) {
///         println!("{}: Delta={:?}, Gamma={:?}", item.name, item.delta, item.gamma);
///     }
///     Ok(())
/// }
/// ```
pub async fn option_risk_analysis_em() -> Result<Vec<OptionRiskAnalysis>> {
    let url = "https://push2.eastmoney.com/api/qt/clist/get";
    let client = build_client()?;
    
    let mut all_data = Vec::new();
    let mut page = 1;
    
    loop {
        let params = [
            ("fid", "f301"),
            ("po", "1"),
            ("pz", "500"),
            ("pn", &page.to_string()),
            ("np", "1"),
            ("fltt", "2"),
            ("invt", "2"),
            ("ut", "b2884a393a59ad64002292a3e90d46a5"),
            ("fields", "f2,f3,f12,f14,f249,f323,f324,f325,f326,f327,f152"),
            ("fs", "m:10"),
        ];
        
        let resp = client.get(url).query(&params).send().await?;
        let json: Value = resp.json().await?;
        
        let data_list = json["data"]["diff"]
            .as_array()
            .ok_or_else(|| anyhow::anyhow!("No data in risk analysis response"))?;
        
        if data_list.is_empty() {
            break;
        }
        
        for item in data_list {
            if let Some(obj) = item.as_object() {
                all_data.push(OptionRiskAnalysis {
                    code: obj.get("f12").and_then(|v| v.as_str()).unwrap_or("").to_string(),
                    name: obj.get("f14").and_then(|v| v.as_str()).unwrap_or("").to_string(),
                    last: obj.get("f2").and_then(|v| v.as_f64()),
                    change_pct: obj.get("f3").and_then(|v| v.as_f64()),
                    delta: obj.get("f323").and_then(|v| v.as_f64()),
                    gamma: obj.get("f324").and_then(|v| v.as_f64()),
                    vega: obj.get("f325").and_then(|v| v.as_f64()),
                    theta: obj.get("f326").and_then(|v| v.as_f64()),
                    rho: obj.get("f327").and_then(|v| v.as_f64()),
                    implied_volatility: obj.get("f249").and_then(|v| v.as_f64()),
                    expire_date: obj.get("f152").and_then(|v| v.as_str()).unwrap_or("").to_string(),
                });
            }
        }
        
        if data_list.len() < 500 {
            break;
        }
        page += 1;
    }
    
    Ok(all_data)
}

/// 东方财富-期权折溢价分析
/// 
/// 获取期权的折溢价率、盈亏平衡价等分析指标
/// 目标地址: https://data.eastmoney.com/other/premium.html
/// 
/// # 返回
/// - `Vec<OptionPremiumAnalysis>`: 包含期权代码、名称、最新价、涨跌幅、折溢价率、
///   行权价、标的最新价、标的涨跌幅、盈亏平衡价、到期日等字段
/// 
/// # 示例
/// ```no_run
/// use akoption::option_premium_analysis_em;
/// 
/// #[tokio::main]
/// async fn main() -> anyhow::Result<()> {
///     let data = option_premium_analysis_em().await?;
///     for item in data.iter().take(5) {
///         println!("{}: 折溢价率={:?}%, 盈亏平衡价={:?}", 
///                  item.name, item.premium_rate, item.break_even);
///     }
///     Ok(())
/// }
/// ```
pub async fn option_premium_analysis_em() -> Result<Vec<OptionPremiumAnalysis>> {
    let url = "https://push2.eastmoney.com/api/qt/clist/get";
    let client = build_client()?;
    
    let mut all_data = Vec::new();
    let mut page = 1;
    
    loop {
        let params = [
            ("fid", "f301"),
            ("po", "1"),
            ("pz", "500"),
            ("pn", &page.to_string()),
            ("np", "1"),
            ("fltt", "2"),
            ("invt", "2"),
            ("ut", "b2884a393a59ad64002292a3e90d46a5"),
            ("fields", "f2,f3,f12,f14,f152,f250,f251,f301,f302,f328"),
            ("fs", "m:10"),
        ];
        
        let resp = client.get(url).query(&params).send().await?;
        let json: Value = resp.json().await?;
        
        let data_list = json["data"]["diff"]
            .as_array()
            .ok_or_else(|| anyhow::anyhow!("No data in premium analysis response"))?;
        
        if data_list.is_empty() {
            break;
        }
        
        for item in data_list {
            if let Some(obj) = item.as_object() {
                all_data.push(OptionPremiumAnalysis {
                    code: obj.get("f12").and_then(|v| v.as_str()).unwrap_or("").to_string(),
                    name: obj.get("f14").and_then(|v| v.as_str()).unwrap_or("").to_string(),
                    last: obj.get("f2").and_then(|v| v.as_f64()),
                    change_pct: obj.get("f3").and_then(|v| v.as_f64()),
                    premium_rate: obj.get("f250").and_then(|v| v.as_f64()),
                    strike: obj.get("f251").and_then(|v| v.as_f64()),
                    underlying_last: obj.get("f301").and_then(|v| v.as_f64()),
                    underlying_change_pct: obj.get("f302").and_then(|v| v.as_f64()),
                    break_even: obj.get("f328").and_then(|v| v.as_f64()),
                    expire_date: obj.get("f152").and_then(|v| v.as_str()).unwrap_or("").to_string(),
                });
            }
        }
        
        if data_list.len() < 500 {
            break;
        }
        page += 1;
    }
    
    Ok(all_data)
}

/// 东方财富-期权分时行情
/// 
/// 获取指定期权合约的分时行情数据
/// 目标地址: https://wap.eastmoney.com/quote/stock/151.cu2404P61000.html
/// 
/// # 参数
/// - `symbol`: 期权代码，例如 "MO2402-C-5400"
/// 
/// # 返回
/// - `Vec<OptionMinute>`: 包含时间、最新价、最高价、最低价、成交量、成交额等字段
/// 
/// # 示例
/// ```no_run
/// use akoption::option_minute_em;
/// 
/// #[tokio::main]
/// async fn main() -> anyhow::Result<()> {
///     let data = option_minute_em("MO2402-C-5400").await?;
///     println!("获取到 {} 条分时数据", data.len());
///     Ok(())
/// }
/// ```
pub async fn option_minute_em(symbol: &str) -> Result<Vec<OptionMinute>> {
    // 需要将 symbol 转换为市场代码格式，例如 MO2402-C-5400 -> 221.MO2402C5400
    let market_code = convert_symbol_to_market_code(symbol)?;
    
    let url = format!("https://push2his.eastmoney.com/api/qt/stock/trends2/get");
    let client = build_client()?;
    
    let params = [
        ("fields1", "f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13"),
        ("fields2", "f51,f52,f53,f54,f55,f56,f57,f58"),
        ("ut", "fa5fd1943c7b386f172d6893dbfba10b"),
        ("secid", &market_code),
        ("ndays", "1"),
    ];
    
    let resp = client.get(&url).query(&params).send().await?;
    let json: Value = resp.json().await?;
    
    let trends = json["data"]["trends"]
        .as_array()
        .ok_or_else(|| anyhow::anyhow!("No trends data in minute response"))?;
    
    let mut result = Vec::new();
    for trend in trends {
        if let Some(trend_str) = trend.as_str() {
            let parts: Vec<&str> = trend_str.split(',').collect();
            if parts.len() >= 6 {
                result.push(OptionMinute {
                    time: parts[0].to_string(),
                    close: parts[2].parse::<f64>().ok(),
                    high: parts[4].parse::<f64>().ok(),
                    low: parts[5].parse::<f64>().ok(),
                    volume: parts[1].parse::<f64>().ok(),
                    amount: parts[3].parse::<f64>().ok(),
                });
            }
        }
    }
    
    Ok(result)
}

/// 将期权代码转换为东方财富市场代码格式
/// 例如: MO2402-C-5400 -> 221.MO2402C5400
fn convert_symbol_to_market_code(symbol: &str) -> Result<String> {
    // 简化处理：移除连字符
    let cleaned = symbol.replace("-", "");
    
    // 根据前缀判断市场代码
    let market = if cleaned.starts_with("IO") || cleaned.starts_with("MO") || cleaned.starts_with("HO") {
        "221" // 中金所期权
    } else if cleaned.starts_with("510") || cleaned.starts_with("588") {
        "10" // 上交所期权
    } else if cleaned.starts_with("159") {
        "12" // 深交所期权
    } else {
        "140" // 商品期权默认
    };
    
    Ok(format!("{}.{}", market, cleaned))
}
